import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.Timer;

/**
 * 
 * Klasse ProgressCircle
 * 
 * @author GUI-Programmer
 * @version 03.10.2011
 */
@SuppressWarnings("serial")
public class ProgressCircle extends JComponent implements ActionListener {
	private boolean mIsRunning;
	private boolean mIsFadingOut;
	private Timer mTimer;

	private int mAngle;
	private int mFadeCount;
	private int mFadeLimit;
	
	
	public ProgressCircle() {
		mFadeLimit = 15;
		setOpaque(false);
	}
	
	public void start() {
		setVisible(true);
		if (mIsRunning) {
			return;
		}
		
		// Run a thread for animation.
		mIsRunning = true;
		mIsFadingOut = false;
		mFadeCount = 0;
		mTimer = new Timer(22, this);
		mTimer.start();
	}
	
	public void stop() {
		mIsFadingOut = true;
		setVisible(false);
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		int w = getWidth();
	    int h = getHeight();
	    super.paintComponent(g);
	    
	    if (!mIsRunning) {
	    	return;
	    }
	    
	    Graphics2D g2 = (Graphics2D) g.create();
	    float fade = (float)mFadeCount / (float)mFadeLimit;
	    // Gray it out.
	    Composite urComposite = g2.getComposite();
	    g2.setComposite(AlphaComposite.getInstance(
	        AlphaComposite.SRC_OVER, .5f * fade));
	    if(isOpaque()) g2.fillRect(0, 0, w, h);
	    g2.setComposite(urComposite);

	    // Paint the wait indicator.
	    int s = Math.min(w, h) / 5;
	    int cx = w / 2;
	    int cy = h / 2;
	    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
	        RenderingHints.VALUE_ANTIALIAS_ON);
	    g2.setStroke(
	        new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
	    g2.setPaint(Color.BLUE);
	    g2.rotate(Math.PI * mAngle / 180, cx, cy);
	    for (int i = 0; i <= 12; i++) {
	      float scale = (12.0f - (float)i) / 12.0f;
	      if(i <= 11) g2.drawLine(cx + s, cy, cx + s * 2, cy);
	      g2.rotate(Math.PI / 6, cx, cy);
	      g2.setComposite(AlphaComposite.getInstance(
	          AlphaComposite.SRC_OVER, scale * fade));
	    }

	    g2.dispose();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(mIsRunning) {
			repaint();
			mAngle += 3;
			if (mAngle >= 360) {
				mAngle = 0;
			}
			if (mIsFadingOut) {
				if (--mFadeCount == 0) {
					mIsRunning = false;
					mTimer.stop();
				}
			}
			else if (mFadeCount < mFadeLimit) {
				mFadeCount++;
			}
		}
	}
}
